/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#include "stub.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "gmock/gmock-actions.h"
#include "SnapshotCommon.h"
#include "SnapshotBackup.h"
#include "PluginUtilities.h"

using ::testing::_;
using testing::AllOf;
using ::testing::AnyNumber;
using ::testing::AtLeast;
using testing::ByMove;
using testing::DoAll;
using ::testing::Eq;
using ::testing::Field;
using ::testing::Ge;
using ::testing::Gt;
using testing::InitGoogleMock;
using ::testing::Invoke;
using ::testing::Ne;
using ::testing::Return;
using ::testing::Sequence;
using ::testing::SetArgReferee;
using ::testing::SetArgumentPointee;
using ::testing::Throw;
using namespace std;


class SnapshotBackupTest : public testing::Test {
public:
    void SetUp();
    void TearDown();
    void SetUpGenSubJobInfo();
    void TearDownGenSubJobInfo();
    void SetUpExecSubJobInfo();
    void TearDownExecSubJobInfo();
    static void SetUpTestCase();
    static void TearDownTestCase();
    unique_ptr<SnapshotBackup> m_snapshotBackup;
    Stub stub;
};

static AppProtect::BackupJob BackupJobSetup()
{
    AppProtect::BackupJob backupJob;
    backupJob.copy.id = "kkkkkkkkkkkkkkkkk";
    backupJob.requestId = "reqId123";
    backupJob.jobId = "jId123";
    backupJob.jobParam.backupType = AppProtect::BackupJobType::FULL_BACKUP;
    backupJob.jobParam.dataLayout.extendInfo = "xxx";
    string filterString;
    AppProtect::ResourceFilter fileFilter;
    fileFilter.filterBy = "Name";
    fileFilter.type = "File";
    fileFilter.mode = "INCLUDE";
    fileFilter.rule = "Fuzzy";
    filterString = "/a";
    fileFilter.values.push_back(filterString);
    AppProtect::ResourceFilter dirFilter;
    dirFilter.filterBy = "Name";
    dirFilter.type = "Dir";
    dirFilter.mode = "INCLUDE";
    dirFilter.rule = "Fuzzy";
    filterString = "/b";
    dirFilter.values.push_back(filterString);
    AppProtect::ResourceFilter formatFilter;
    formatFilter.filterBy = "Format";
    formatFilter.type = "File";
    formatFilter.mode = "INCLUDE";
    formatFilter.rule = "Exact";
    filterString = "1";
    formatFilter.values.push_back(filterString);
    filterString = "2";
    formatFilter.values.push_back(filterString);
    filterString = "3";
    formatFilter.values.push_back(filterString);
    filterString = "4";
    formatFilter.values.push_back(filterString);
    filterString = "5";
    formatFilter.values.push_back(filterString);
    filterString = "6";
    formatFilter.values.push_back(filterString);
    AppProtect::ResourceFilter dateFilter;
    dateFilter.filterBy = "ModifyTime";
    dateFilter.type = "File";
    dateFilter.mode = "INCLUDE";
    dateFilter.rule = "Exact";
    filterString = "1641839400533";
    dateFilter.values.push_back(filterString);
    filterString = "1641943800694";
    dateFilter.values.push_back(filterString);
    backupJob.jobParam.filters.push_back(fileFilter);
    backupJob.jobParam.filters.push_back(dirFilter);
    backupJob.jobParam.filters.push_back(formatFilter);
    backupJob.jobParam.filters.push_back(dateFilter);
    backupJob.jobParam.advanceParams = "{\"small_file_aggregation\":\"0\",\"aggregate_level\":\"0\","
        "\"permissions_and_attributes\":\"1\"}";
    backupJob.protectEnv.id = "peId123";
    backupJob.protectEnv.name = "poName123";
    backupJob.protectEnv.type = "Vendor";
    backupJob.protectEnv.subType = "StorageOthers";
    backupJob.protectEnv.endpoint = "10.28.12.144";
    backupJob.protectEnv.port = 8080;
    backupJob.protectEnv.auth.extendInfo = "{\"fingerPrint\" : \"4928EBB6E58A3A395BC89317DD55B82F1B8C10E7\"}";
    backupJob.protectEnv.extendInfo = "{\"snapConsistency\":\"0\",\"verifyStatus\":\"1\",\"wwn\":\"\"}";
    backupJob.protectObject.id = "poID123";
    backupJob.protectObject.type = "storage";
    backupJob.protectObject.subType = "NasShare";
    backupJob.protectObject.name = "OceanstorFS";
    backupJob.protectObject.auth.authType = AuthType::NO_AUTHENTICATION;
    backupJob.protectObject.auth.authkey = "";
    backupJob.protectObject.auth.authPwd = "";
    backupJob.protectObject.extendInfo = "{\"authMode\":\"1\",\"filters\":\"\",\"ip\":\"10.28.12.144\""
        ",\"kerberosId\":\"0\",\"shareMode\":\"1\"}";
    string path = "/MetaFS/cache";
    HostAddress hostadd;
    hostadd.ip = "10.28.12.144";
    StorageRepository cacheRepo;
    cacheRepo.repositoryType = RepositoryDataType::CACHE_REPOSITORY;
    cacheRepo.path.push_back(path);
    cacheRepo.remotePath = "/MetaFS/cache";
    cacheRepo.remoteHost.push_back(hostadd);
    cacheRepo.auth.authkey = "admin";
    cacheRepo.auth.authPwd = "Admin@123";
    cacheRepo.endpoint.ip = "10.28.12.144";
    cacheRepo.endpoint.port = 8088;
    StorageRepository dataRepo;
    dataRepo.repositoryType = RepositoryDataType::DATA_REPOSITORY;
    dataRepo.remotePath = "/BackupFS";
    dataRepo.path.push_back(dataRepo.remotePath);
    dataRepo.remoteHost.push_back(hostadd);
    dataRepo.auth.authkey = "admin";
    dataRepo.auth.authPwd = "Admin@123";
    dataRepo.endpoint.ip = "10.28.12.144";
    dataRepo.endpoint.port = 8088;
    StorageRepository metaRepo;
    metaRepo.repositoryType = RepositoryDataType::META_REPOSITORY;
    path = "/MetaFS/meta";
    metaRepo.path.push_back(path);
    metaRepo.remotePath = "/MetaFS/meta";
    metaRepo.remoteHost.push_back(hostadd);
    metaRepo.auth.authkey = "admin";
    metaRepo.auth.authPwd = "Admin@123";
    metaRepo.endpoint.ip = "10.28.12.144";
    metaRepo.endpoint.port = 8088;
    backupJob.repositories.push_back(cacheRepo);
    backupJob.repositories.push_back(dataRepo);
    backupJob.repositories.push_back(metaRepo);
    backupJob.extendInfo = "{\"auto_index\":\"false\",\"permissions_and_attributes\":\"0\",\"proxy_host_mode\":\"0\","
        "\"small_file_aggregation\":\"0\"}";
    return backupJob;
}

static SubJob CreateSubJob()
{
    SubJob subJob;
    subJob.jobId = "jobId123";
    subJob.subJobId = "subJob123";
    subJob.jobName = "XYZ";
    subJob.jobPriority = 1;
    subJob.jobInfo = "{\"ControlFile\":\"\",\"SubTaskType\":1,\"Ext\":\"\"}";
    return subJob;
}

void SnapshotBackupTest::SetUp()
{
    m_snapshotBackup = std::make_unique<SnapshotBackup>();
    m_snapshotBackup->m_jobCommonInfo = std::make_shared<JobCommonInfo>(std::make_shared<BackupJob>(BackupJobSetup()));
}

void SnapshotBackupTest::TearDown() {}

void SnapshotBackupTest::SetUpTestCase() {}

void SnapshotBackupTest::TearDownTestCase() {}


shared_ptr<ThriftDataBase> GetJobInfo_Stub()
{
    BackupJob backupJob;
    auto jobInfoBackup = std::make_shared<JobCommonInfo>(std::make_shared<BackupJob>(backupJob));
}

static int PrerequisiteJobInner_Stub_Fail()
{
    return Module::FAILED;
}

static void ReportJobDetails_Stub()
{
    return;
}

static int CheckNetwork_Stub(void *obj)
{
    return Module::SUCCESS;
}

static std::string GetDeployType_stub_secure_machine()
{
    cout << "Enter GetDeployType_stub_secure_machine" << endl;
    return "d5";
}

static std::string GetDeployType_stub_anti_ransomware()
{
    cout << "Enter GetDeployType_stub_anti_ransomware" << endl;
    return "d4";
}

static int CreateSnapshotWithSnapTagAndVstoreId_Stub_Suc(void *obj)
{
    return Module::SUCCESS;
}

static int CreateSnapshotWithSnapTagAndVstoreId_Stub_Fail(void *obj)
{
    return Module::FAILED;
}

static int QuerySnapshot_Stub_Suc()
{
    return Module::SUCCESS;
}

static int QuerySnapshot_Stub_Fail()
{
    return Module::FAILED;
}

static int DeleteSnapshot_Stub_Suc()
{
    return Module::SUCCESS;
}

static int DeleteSnapshot_Stub_Fail()
{
    return Module::FAILED;
}

static int InitDeviceInfo_Stub_Suc()
{
    return Module::SUCCESS;
}

static int InitDeviceInfo_Stub_Fail()
{
    return Module::FAILED;
}

static int ReportJobDetails_stub(void *obj)
{
    return Module::SUCCESS;
}

static int ReportCopyInfo_Stub(void *obj)
{
    return Module::SUCCESS;
}

static void ReportCopyAdditionalInfo_Stub(void *obj)
{
    return;
}

static void AddNewJob_Stub()
{
    return;
}

/*
 * 用例名称：PrerequisiteJob_Su
 * 前置条件：无
 * check点：前置任务成功
 */
TEST_F(SnapshotBackupTest, PrerequisiteJob_Suc)
{
    stub.set((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
        const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails),
        ReportJobDetails_Stub);

    int ret = m_snapshotBackup->PrerequisiteJob();
    EXPECT_EQ(ret, Module::SUCCESS);

    stub.reset((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
        const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails));
}

/*
 * 用例名称：PrerequisiteJob_Fail
 * 前置条件：无
 * check点：前置任务失败
 */
TEST_F(SnapshotBackupTest, PrerequisiteJob_Fail)
{
    stub.set((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
        const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails),
        ReportJobDetails_Stub);
    stub.set(ADDR(SnapshotBackup, PrerequisiteJobInner), PrerequisiteJobInner_Stub_Fail);

    EXPECT_EQ(m_snapshotBackup->PrerequisiteJob(), Module::FAILED);

    stub.reset(ADDR(SnapshotBackup, PrerequisiteJobInner));
    stub.reset((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
        const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails));
}

/*
 * 用例名称：GenerateSubJob_Suc
 * 前置条件：无
 * check点：生成子任务成功
 */
TEST_F(SnapshotBackupTest, GenerateSubJob_Suc)
{
    stub.set((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
        const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails),
        ReportJobDetails_Stub);
    stub.set(ADDR(JobService, AddNewJob), AddNewJob_Stub);

    EXPECT_EQ(m_snapshotBackup->GenerateSubJob(), Module::SUCCESS);

    stub.reset(ADDR(JobService, AddNewJob));
    stub.reset((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
        const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails));
}

/*
 * 用例名称：GenerateSubJob_Suc
 * 前置条件：无
 * check点：生成子任务失败
 */
TEST_F(SnapshotBackupTest, GenerateSubJob_Fail)
{
    stub.set((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
        const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails),
        ReportJobDetails_Stub);

    int ret = m_snapshotBackup->GenerateSubJob();
    EXPECT_EQ(ret, Module::FAILED);

    stub.reset((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
        const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails));
}

/*
 * 用例名称：ExecuteSubJob_Suc
 * 前置条件：无
 * check点：执行子任务成功
 */
TEST_F(SnapshotBackupTest, ExecuteSubJob_Suc)
{
    std::shared_ptr<SubJob> subJobptr = std::make_shared<SubJob>(CreateSubJob());
    m_snapshotBackup->SetSubJob(subJobptr);

    // stub.set(ADDR(SnapshotCommon, CheckNetwork), CheckNetwork_Stub);
    stub.set(ADDR(Module::DoradoNas, CreateSnapshotWithSnapTagAndVstoreId),
        CreateSnapshotWithSnapTagAndVstoreId_Stub_Suc);
    stub.set(ADDR(JobService, ReportJobDetails), ReportJobDetails_stub);
    stub.set(PluginUtils::GetDeployType, GetDeployType_stub_anti_ransomware);

    EXPECT_EQ(m_snapshotBackup->ExecuteSubJob(), Module::SUCCESS);

    // stub.reset(ADDR(SnapshotCommon, CheckNetwork));
    stub.reset(ADDR(Module::DoradoNas, CreateSnapshotWithSnapTagAndVstoreId));
    stub.reset(ADDR(JobService, ReportJobDetails));
    stub.reset(PluginUtils::GetDeployType);
}

/*
 * 用例名称：ExecuteSubJob_InitJobInfoFail
 * 前置条件：无
 * check点：执行子任务，InitJobInfo失败异常流程
 *       */
TEST_F(SnapshotBackupTest, ExecuteSubJob_InitJobInfoFail)
{
    std::shared_ptr<SubJob> subJobptr = std::make_shared<SubJob>(CreateSubJob());
    m_snapshotBackup->SetSubJob(subJobptr);

    // stub.set(ADDR(SnapshotCommon, CheckNetwork), CheckNetwork_Stub);
    stub.set(ADDR(Module::DoradoNas, CreateSnapshotWithSnapTagAndVstoreId),
        CreateSnapshotWithSnapTagAndVstoreId_Stub_Suc);
    stub.set(ADDR(JobService, ReportJobDetails), ReportJobDetails_stub);
    stub.set(PluginUtils::GetDeployType, GetDeployType_stub_anti_ransomware);

    // 设置extendInfo为空，JsonHelper::JsonStringToStruct返回false，走异常流程
    std::shared_ptr<BackupJob> jobInfoPtr =
        dynamic_pointer_cast<BackupJob>(m_snapshotBackup->m_jobCommonInfo->GetJobInfo());
    jobInfoPtr->protectObject.extendInfo = "";
    EXPECT_EQ(m_snapshotBackup->ExecuteSubJob(), Module::FAILED);

    // stub.reset(ADDR(SnapshotCommon, CheckNetwork));
    stub.reset(ADDR(Module::DoradoNas, CreateSnapshotWithSnapTagAndVstoreId));
    stub.reset(ADDR(JobService, ReportJobDetails));
    stub.reset(PluginUtils::GetDeployType);

}

/*
 * 用例名称：ExecuteSubJob_InitDeviceInfoFail
 * 前置条件：无
 * check点：执行子任务，InitDeviceInfo失败异常流程
 *       */
TEST_F(SnapshotBackupTest, ExecuteSubJob_InitDeviceInfoFail)
{
    std::shared_ptr<SubJob> subJobptr = std::make_shared<SubJob>(CreateSubJob());
    m_snapshotBackup->SetSubJob(subJobptr);

    stub.set(ADDR(Module::DoradoNas, CreateSnapshotWithSnapTagAndVstoreId),
        CreateSnapshotWithSnapTagAndVstoreId_Stub_Suc);
    // stub.set(ADDR(SnapshotCommon, CheckNetwork), CheckNetwork_Stub);
    stub.set(ADDR(JobService, ReportJobDetails), ReportJobDetails_stub);
    stub.set(ADDR(SnapshotCommon, InitDeviceInfo), InitDeviceInfo_Stub_Fail);
    stub.set(PluginUtils::GetDeployType, GetDeployType_stub_anti_ransomware);

    EXPECT_EQ(m_snapshotBackup->ExecuteSubJob(), Module::FAILED);

    stub.reset(ADDR(SnapshotCommon, InitDeviceInfo));
    stub.reset(ADDR(JobService, ReportJobDetails));
    // stub.reset(ADDR(SnapshotCommon, CheckNetwork));
    stub.reset(ADDR(Module::DoradoNas, CreateSnapshotWithSnapTagAndVstoreId));
    stub.reset(PluginUtils::GetDeployType);
}

/*
 * 用例名称：ExecuteSubJob_CreateSnapshotFail
 * 前置条件：无
 * check点：执行子任务，CreateSnapshot时失败异常流程
 */
TEST_F(SnapshotBackupTest, ExecuteSubJob_CreateSnapshotFail)
{
    std::shared_ptr<SubJob> subJobptr = std::make_shared<SubJob>(CreateSubJob());
    m_snapshotBackup->SetSubJob(subJobptr);

    stub.set(ADDR(Module::DoradoNas, CreateSnapshotWithSnapTagAndVstoreId),
        CreateSnapshotWithSnapTagAndVstoreId_Stub_Fail);
    // stub.set(ADDR(SnapshotCommon, CheckNetwork), CheckNetwork_Stub);
    stub.set(ADDR(JobService, ReportJobDetails), ReportJobDetails_stub);
    stub.set(PluginUtils::GetDeployType, GetDeployType_stub_anti_ransomware);

    // CreateSnapshotWithSnapTagAndVstoreId返回失败->CreateSnapshot失败
    EXPECT_EQ(m_snapshotBackup->ExecuteSubJob(), Module::FAILED);

    stub.reset(ADDR(JobService, ReportJobDetails));
    // stub.reset(ADDR(SnapshotCommon, CheckNetwork));
    stub.reset(ADDR(Module::DoradoNas, CreateSnapshotWithSnapTagAndVstoreId));
    stub.reset(PluginUtils::GetDeployType);
}

/*
 * 用例名称：PostJob
 * 前置条件：无
 * check点：post任务成功
 */
// TEST_F(SnapshotBackupTest, PostJob)
// {
//     std::shared_ptr<SubJob> subJobptr = std::make_shared<SubJob>(CreateSubJob());
//     m_snapshotBackup->SetSubJob(subJobptr);

//     stub.set((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
//         const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails),
//         ReportJobDetails_Stub);
//     stub.set(ADDR(SnapshotCommon, CheckNetwork), CheckNetwork_Stub);
//     stub.set(ADDR(Module::DoradoNas, QuerySnapshot), QuerySnapshot_Stub_Suc);
//     stub.set(ADDR(JobService, ReportCopyAdditionalInfo), ReportCopyAdditionalInfo_Stub);
//     stub.set(PluginUtils::GetDeployType, GetDeployType_stub_anti_ransomware);

//     int ret = m_snapshotBackup->PostJob();
//     EXPECT_EQ(ret, Module::SUCCESS);

//     stub.reset((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
//         const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails));
//     stub.reset(ADDR(SnapshotCommon, CheckNetwork));
//     stub.reset(ADDR(Module::DoradoNas, QuerySnapshot));
//     stub.reset(ADDR(JobService, ReportCopyAdditionalInfo));
//     stub.reset(PluginUtils::GetDeployType);
// }

/*
 * 用例名称：PostJob_JobFailed_CopyIdNull
 * 前置条件：无
 * check点：任务流程成功，ReportCopyInfo内部QuerySnapshot失败异常流程
 */
// TEST_F(SnapshotBackupTest, PostJob_QuerySnapshotFail)
// {
//     std::shared_ptr<SubJob> subJobptr = std::make_shared<SubJob>(CreateSubJob());
//     m_snapshotBackup->SetSubJob(subJobptr);

//     stub.set((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
//         const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails),
//         ReportJobDetails_Stub);
//     stub.set(ADDR(SnapshotCommon, CheckNetwork), CheckNetwork_Stub);
//     stub.set(ADDR(Module::DoradoNas, QuerySnapshot), QuerySnapshot_Stub_Fail);
//     typedef int (*fptr)(Module::DoradoNas *, std::string);
//     fptr DoradoNas_deleteSnapshot =
//         (fptr)((int (Module::DoradoNas::*)(std::string)) & Module::DoradoNas::DeleteSnapshot);
//     stub.set(DoradoNas_deleteSnapshot, DeleteSnapshot_Stub_Suc);
//     stub.set(ADDR(JobService, ReportCopyAdditionalInfo), ReportCopyAdditionalInfo_Stub);
//     stub.set(PluginUtils::GetDeployType, GetDeployType_stub_anti_ransomware);

//     int ret = m_snapshotBackup->PostJob();
//     EXPECT_EQ(ret, Module::FAILED);

//     stub.reset((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
//         const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails));
//     stub.reset(ADDR(SnapshotCommon, CheckNetwork));
//     stub.reset(ADDR(Module::DoradoNas, QuerySnapshot));
//     stub.reset(DoradoNas_deleteSnapshot);
//     stub.reset(ADDR(JobService, ReportCopyAdditionalInfo));
//     stub.reset(PluginUtils::GetDeployType);
// }

/*
 * 用例名称：PostJob_JobFailed_CopyIdNull
 * 前置条件：无
 * check点：jobInfo的extendInfo转换Json失败，走异常流程
 */
TEST_F(SnapshotBackupTest, PostJob_InitJobInfoFail)
{
    std::shared_ptr<SubJob> subJobptr = std::make_shared<SubJob>(CreateSubJob());
    m_snapshotBackup->SetSubJob(subJobptr);

    stub.set((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
        const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails),
        ReportJobDetails_Stub);
    stub.set(PluginUtils::GetDeployType, GetDeployType_stub_anti_ransomware);

    // 设置extendInfo为空，JsonHelper::JsonStringToStruct返回false，走异常流程
    std::shared_ptr<BackupJob> jobInfoPtr =
        dynamic_pointer_cast<BackupJob>(m_snapshotBackup->m_jobCommonInfo->GetJobInfo());
    jobInfoPtr->protectObject.extendInfo = "";
    int ret = m_snapshotBackup->PostJob();
    EXPECT_EQ(ret, Module::FAILED);

    stub.reset((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
        const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails));
    stub.reset(PluginUtils::GetDeployType);
}

/*
 * 用例名称：PostJob_JobFailed_CopyIdNull
 * 前置条件：无
 * check点：jobInfo的extendInfo转换Json失败，走异常流程
 */
TEST_F(SnapshotBackupTest, PostJob_InitDeviceInfoFail)
{
    std::shared_ptr<SubJob> subJobptr = std::make_shared<SubJob>(CreateSubJob());
    m_snapshotBackup->SetSubJob(subJobptr);

    stub.set((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
        const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails),
        ReportJobDetails_Stub);
    stub.set(ADDR(SnapshotCommon, InitDeviceInfo), InitDeviceInfo_Stub_Fail);
    stub.set(PluginUtils::GetDeployType, GetDeployType_stub_anti_ransomware);

    int ret = m_snapshotBackup->PostJob();
    EXPECT_EQ(ret, Module::FAILED);

    stub.reset(ADDR(SnapshotCommon, InitDeviceInfo));
    stub.reset((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
        const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails));
    stub.reset(PluginUtils::GetDeployType);
}

/*
 * 用例名称：PostJob_JobFailed
 * 前置条件：无
 * check点：任务流标记失败
 */
// TEST_F(SnapshotBackupTest, PostJob_JobResultFail)
// {
//     std::shared_ptr<SubJob> subJobptr = std::make_shared<SubJob>(CreateSubJob());
//     m_snapshotBackup->SetSubJob(subJobptr);

//     stub.set((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
//         const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails),
//         ReportJobDetails_Stub);
//     stub.set(ADDR(SnapshotCommon, CheckNetwork), CheckNetwork_Stub);
//     stub.set(ADDR(Module::DoradoNas, QuerySnapshot), QuerySnapshot_Stub_Suc);
//     stub.set(PluginUtils::GetDeployType, GetDeployType_stub_anti_ransomware);

//     typedef int (*fptr)(Module::DoradoNas *, std::string);
//     fptr DoradoNas_deleteSnapshot =
//         (fptr)((int (Module::DoradoNas::*)(std::string)) & Module::DoradoNas::DeleteSnapshot);
//     stub.set(DoradoNas_deleteSnapshot, DeleteSnapshot_Stub_Suc);
//     stub.set(ADDR(JobService, ReportCopyAdditionalInfo), ReportCopyAdditionalInfo_Stub);

//     // 设置任务失败
//     m_snapshotBackup->m_backupJobResult = AppProtect::JobResult::type::FAILED;
//     int ret = m_snapshotBackup->PostJob();
//     EXPECT_EQ(ret, Module::SUCCESS);

//     stub.reset((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
//         const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails));
//     stub.reset(ADDR(SnapshotCommon, CheckNetwork));
//     stub.reset(ADDR(Module::DoradoNas, QuerySnapshot));
//     stub.reset(DoradoNas_deleteSnapshot);
//     stub.reset(ADDR(JobService, ReportCopyAdditionalInfo));
//     stub.reset(PluginUtils::GetDeployType);
// }

/*
 * 用例名称：PostJob_DeleteBackupSnapshot_1
 * 前置条件：无
 * check点：DeleteBackupSnapshot函数 copy.id为空时走snapshotName为空异常分支
 */
// TEST_F(SnapshotBackupTest, PostJob_DeleteBackupSnapshot_1)
// {
//     std::shared_ptr<SubJob> subJobptr = std::make_shared<SubJob>(CreateSubJob());
//     m_snapshotBackup->SetSubJob(subJobptr);

//     stub.set((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
//         const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails),
//         ReportJobDetails_Stub);
//     stub.set(ADDR(SnapshotCommon, CheckNetwork), CheckNetwork_Stub);
//     stub.set(ADDR(Module::DoradoNas, QuerySnapshot), QuerySnapshot_Stub_Suc);
//     typedef int (*fptr)(Module::DoradoNas *, std::string);
//     fptr DoradoNas_deleteSnapshot =
//         (fptr)((int (Module::DoradoNas::*)(std::string)) & Module::DoradoNas::DeleteSnapshot);
//     stub.set(DoradoNas_deleteSnapshot, DeleteSnapshot_Stub_Suc);
//     stub.set(ADDR(JobService, ReportCopyAdditionalInfo), ReportCopyAdditionalInfo_Stub);
//     stub.set(PluginUtils::GetDeployType, GetDeployType_stub_anti_ransomware);

//     // 设置任务失败
//     m_snapshotBackup->m_backupJobResult = AppProtect::JobResult::type::FAILED;
//     // 设置copy id为空
//     std::shared_ptr<BackupJob> jobInfoPtr =
//         dynamic_pointer_cast<BackupJob>(m_snapshotBackup->m_jobCommonInfo->GetJobInfo());
//     jobInfoPtr->copy.id = "";
//     int ret = m_snapshotBackup->PostJob();
//     EXPECT_EQ(ret, Module::FAILED);

//     stub.reset((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
//         const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails));
//     stub.reset(ADDR(SnapshotCommon, CheckNetwork));
//     stub.reset(ADDR(Module::DoradoNas, QuerySnapshot));
//     stub.reset(DoradoNas_deleteSnapshot);
//     stub.reset(ADDR(JobService, ReportCopyAdditionalInfo));
//     stub.reset(PluginUtils::GetDeployType);
// }


/*
 * 用例名称：PostJob_DeleteBackupSnapshot_2
 * 前置条件：无
 * check点：任务流标记失败，删除副本成功，返回任务成功
 */
// TEST_F(SnapshotBackupTest, PostJob_DeleteBackupSnapshot_2)
// {
//     std::shared_ptr<SubJob> subJobptr = std::make_shared<SubJob>(CreateSubJob());
//     m_snapshotBackup->SetSubJob(subJobptr);

//     stub.set((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
//         const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails),
//         ReportJobDetails_Stub);
//     stub.set(ADDR(SnapshotCommon, CheckNetwork), CheckNetwork_Stub);
//     stub.set(ADDR(Module::DoradoNas, QuerySnapshot), QuerySnapshot_Stub_Fail);
//     typedef int (*fptr)(Module::DoradoNas *, std::string);
//     fptr DoradoNas_deleteSnapshot =
//         (fptr)((int (Module::DoradoNas::*)(std::string)) & Module::DoradoNas::DeleteSnapshot);
//     stub.set(DoradoNas_deleteSnapshot, DeleteSnapshot_Stub_Suc);
//     stub.set(ADDR(JobService, ReportCopyAdditionalInfo), ReportCopyAdditionalInfo_Stub);
//     stub.set(PluginUtils::GetDeployType, GetDeployType_stub_anti_ransomware);

//     // 设置任务失败
//     m_snapshotBackup->m_backupJobResult = AppProtect::JobResult::type::FAILED;
//     int ret = m_snapshotBackup->PostJob();
//     EXPECT_EQ(ret, Module::SUCCESS);

//     stub.reset((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
//         const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails));
//     stub.reset(ADDR(SnapshotCommon, CheckNetwork));
//     stub.reset(ADDR(Module::DoradoNas, QuerySnapshot));
//     stub.reset(DoradoNas_deleteSnapshot);
//     stub.reset(ADDR(JobService, ReportCopyAdditionalInfo));
//     stub.reset(PluginUtils::GetDeployType);
// }

/*
 * 用例名称：PostJob_DeleteBackupSnapshot_3
 * 前置条件：无
 * check点：任务流标记失败，DeleteBackupSnapshot函数 DeleteSnapshot失败时时走异常分支
 */
// TEST_F(SnapshotBackupTest, PostJob_DeleteBackupSnapshot_3)
// {
//     std::shared_ptr<SubJob> subJobptr = std::make_shared<SubJob>(CreateSubJob());
//     m_snapshotBackup->SetSubJob(subJobptr);

//     stub.set((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
//         const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails),
//         ReportJobDetails_Stub);
//     stub.set(ADDR(SnapshotCommon, CheckNetwork), CheckNetwork_Stub);
//     stub.set(ADDR(Module::DoradoNas, QuerySnapshot), QuerySnapshot_Stub_Suc);
//     typedef int (*fptr)(Module::DoradoNas *, std::string);
//     fptr DoradoNas_deleteSnapshot =
//         (fptr)((int (Module::DoradoNas::*)(std::string)) & Module::DoradoNas::DeleteSnapshot);
//     stub.set(DoradoNas_deleteSnapshot, DeleteSnapshot_Stub_Fail);
//     stub.set(ADDR(JobService, ReportCopyAdditionalInfo), ReportCopyAdditionalInfo_Stub);
//     stub.set(PluginUtils::GetDeployType, GetDeployType_stub_anti_ransomware);

//     // 设置任务失败
//     m_snapshotBackup->m_backupJobResult = AppProtect::JobResult::type::FAILED;
//     int ret = m_snapshotBackup->PostJob();
//     EXPECT_EQ(ret, Module::FAILED);

//     stub.reset((void (SnapshotBackup::*)(const std::string &label, const JobLogLevel::type &level,
//         const SubJobStatus::type sts, int progress))ADDR(SnapshotBackup, ReportJobDetails));
//     stub.reset(ADDR(SnapshotCommon, CheckNetwork));
//     stub.reset(ADDR(Module::DoradoNas, QuerySnapshot));
//     stub.reset(DoradoNas_deleteSnapshot);
//     stub.reset(ADDR(JobService, ReportCopyAdditionalInfo));
//     stub.reset(PluginUtils::GetDeployType);
// }
